package com.brian.ratelimit.controller;

import com.brian.ratelimit.annotation.BrianLimit;
import com.brian.ratelimit.service.OrderService;
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: architect 使用RateLimiter实现令牌桶限流
 * @author: Brian Huang
 * @create: 2019-05-25 11
 **/

@RestController
public class IndexController {

    @Autowired
    private OrderService orderService;

    /**
     * create方法是以一个独立的线程以恒定的速率 1r/s 的速率往桶中存入一个令牌
     */
    RateLimiter limiter = RateLimiter.create(100.0);



    @GetMapping("/seckill")
    public ResponseEntity<?> seckill() throws InterruptedException {

        //limiter.acquire()从桶中拿到令牌的等待时间
        double acq = limiter.acquire();
        //如果500毫秒内没有获取到令牌的话，则直接走服务降级处理
        boolean acquire = limiter.tryAcquire(500, TimeUnit.MILLISECONDS);
        if(!acquire){
            Map<String,String> map = new HashMap<>();
            map.put("code","200");
            map.put("message","服务忙，请稍后提交！！！");
            System.out.println(Thread.currentThread().getName() + " 等待时间:" +acq);
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        return new ResponseEntity<>(orderService.order(), HttpStatus.OK);
    }



    @GetMapping("/order")
    @BrianLimit(permitsPerSecond = 1.0 ,timeout = 500)
    public ResponseEntity<?> order() throws InterruptedException {
        return new ResponseEntity<>(orderService.order(), HttpStatus.OK);
    }
}
